<template>
	<view class="nx-turn">
		<view
			class="nx-turn-page-wrapper turn"
			@touchstart="touchStart"
			@touchmove="touchMove"
			@touchend="touchEnd"
			@touchcancel="touchCancel"
		>
			<view
				class="nx-turn-page-content-wrapper"
				:style="{
					width: `${pageContentWrapperWidth}px`,
					height: `${pageContentWrapperWidth}px`,
					...transformStyle.wrapper
				}"
			>
				<view
					class="nx-turn-page-content-box"
					:class="customClass"
					:style="{
						width: `${pageWrapperInfo.width}px`,
						height: `${pageWrapperInfo.height}px`,
						...customStyle,
						...transformStyle.content,
					}"
				>
					<slot name="page-content" :page="page"></slot>
				</view>
			</view>
			<view
				class="nx-turn-page-content-wrapper nx-turn-page-content-wrapper-b"
				:style="{
					width: `${pageContentWrapperWidth}px`,
					height: `${pageContentWrapperWidth}px`,
					...transformStyle.bwrapper
				}"
			>
				<view
					class="nx-turn-page-content-box nx-turn-page-content-b-box"
					:class="customClass"
					:style="{
						width: `${pageWrapperInfo.width}px`,
						height: `${pageWrapperInfo.height}px`,
						...customStyle,
						...transformStyle.bcontent
					}"
				>
					<view
						class="nx-turn-page-content-wrapper-b-shadow"
						:style="{
							width: `${pageWrapperInfo.width}px`,
							height: `${pageWrapperInfo.height}px`,
							...transformStyle.bgradient
						}"
					></view>
					<view class="nx-turn-page-content-b"></view>
				</view>
			</view>
			<view
				:style="{
					width: `${pageWrapperInfo.width}px`,
					height: `${pageWrapperInfo.height}px`,
					...transformStyle.gradient
				}"
			></view>
		</view>
		<view 
			class="nx-turn-page-wrapper next" 
			:class="customClass" 
			:style="customStyle"
		>
			<slot name="next-page-content" :page="page + 1"></slot>
		</view>
	</view>
</template>

<script>
	import {
		getPageDiagonalLength,
		point2D,
		touchStartEvent,
		touchMoveEvent,
		touchEndEvent,
		setPageNumber,
		setPageCount
	} from './js/nx-turn.js';
	export default {
		name:"nx-turn",
		props: {
			/**
			 * 初始页码，从0开始
			 */
			initPage: {
				type: Number,
				default: 0
			},
			/**
			 * 页数
			 */
			pageCount: {
				type: Number,
				default: -1
			},
			customClass: {
				type: String,
				default: 'nx-turn-theme'
			},
			customStyle: {
				type: Object,
				default: {}
			}
		},
		data() {
			return {
				// 起始触摸点X坐标
				touchStartX: 0,
				// 起始触摸点Y坐标
				touchStartY: 0,
				// 书页内容包装外框宽度（等于书页对角线长度）
				pageContentWrapperWidth: 0,
				// 书页包装外框信息
				pageWrapperInfo: { width: 0, height: 0 },
				// 变换样式
				transformStyle: {},
				// 当前页码
				page: 0,
				mouseIsDown: false
			};
		},
		created() {
			this.setPage();
			setPageCount(this.pageCount);
		},
		mounted() {
			this.$nextTick(() => {
				this.init();
			});
		},
		watch: {
			initPage() {
				this.setPage();
			},
			pageCount(newValue) {
				setPageCount(newValue);
			}
		},
		methods: {
			init() {
				const query = uni.createSelectorQuery().in(this);
				query
					.select('.nx-turn-page-wrapper.turn')
					.boundingClientRect(async (data) => {
						this.pageWrapperInfo = data;
						this.pageContentWrapperWidth = getPageDiagonalLength(data);
						this.$emit('init-completed', this.pageWrapperInfo);
					})
					.exec();
			},
			setPage() {
				this.page = this.initPage;
				setPageNumber(this.page);
			},
			touchStart(e) {
				this.touchStartX = e.touches[0].clientX;
				this.touchStartY = e.touches[0].clientY;
				touchStartEvent(this.pageWrapperInfo, point2D(this.touchStartX, this.touchStartY));
			},
			mouseDown(e) {
				this.mouseIsDown = true;
				this.touchStart(e);
			},
			touchMove(e) {
				// this.closeMenu();
				const point = e.touches[0];
				const { style, pageNumber } = touchMoveEvent(point2D(point.clientX, point.clientY));
				this.transformStyle = style;
				this.page = pageNumber;
				this.$emit('turning');
			},
			mouseMove(e) {
				if(this.mouseIsDown) {
					this.touchMove(e);
				}
			},
			touchEnd(e) {
				e.preventDefault();
				const point = e.changedTouches[0];
				this.handleTouchEnd(point2D(point.clientX, point.clientY));
			},
			mouseUp(e) {
				this.mouseIsDown = false;
				this.touchEnd(e);
			},
			touchCancel(e) {
				this.handleTouchEnd(point2D(this.touchStartX, this.touchStartY));
			},
			handleTouchEnd(point) {
				touchEndEvent(
					point,
					({ style, pageNumber }) => {
						// this.closeMenu();
						this.transformStyle = style;
						this.page = pageNumber;
						this.$emit('turning');
					},
					({ style, pageNumber, isFirst, isLast }) => {
						this.transformStyle = style;
						this.page = pageNumber;
						this.$emit('turned', { pageNumber, isFirst, isLast });
					},
					() => {
						this.$emit('click-center');
					}
				);
			},
		}
	}
</script>

<style lang="scss">
	.nx-turn {
		width: 100%;
		height: 100%;
		&-page {
			&-wrapper {
				position: absolute;
				overflow: hidden;
				height: 100%;
				width: 100%;
				perspective: 1000px;
				&.turn {
					z-index: 20;
				}
				&.next {
					z-index: 10;
				}
			}
			&-content {
				height: 100%;
				&-wrapper {
					position: absolute;
					top: 0px;
					left: 0px;
					overflow: hidden;
					z-index: auto;
					transform-origin: 0% 100%;
					&-b {
						transform: translate(-100%, 0);
						&-shadow {
							position: absolute;
							top: 0px;
							left: 0px;
							overflow: hidden;
							z-index: 1;
						}
					}
				}
				&-box {
					position: absolute;
				}
			}
		}
		&-theme {
			background-color: #EBD6B1;
			color: mix(#000000, #EBD6B1, 70%);
			border-color: mix(#FFFFFF, #EBD6B1, 70%);
		}
	}
</style>